import React from 'react';
import * as Sentry from '@sentry/react';
import { BrowserTracing } from '@sentry/tracing';
import { permsMap, routeMenuStructuredData } from '@config/index';

//storage的命名空间
const storageKeyName = 'defaultApp';
type storeType = 'session' | 'local';

//sessionStorage存储类型定义
interface SessionStorageType {
    testFieldAge: number;
    testCountMemory: number;
}

interface RoleItem {
    orgId: string;
    roleId: string;
    roleName: string;
    shared: boolean;
    systemCode: string;
    systemName: string;
}

//LocalStorageType存储类型定义
interface LocalStorageType {
    testFieldAge: number;
    language: string;
    innerPagesRoutePermsMap: Record<string, any>;
    originMenuList: Record<string, unknown>[];
    menuList: Record<string, unknown>[];
    urlList: string[];
    permList: string[];
    frontCodeList: string[];
    userInfo: Record<string, unknown>;
    token: string;
    menuState: {
        openKeys: string[];
        selectedKeys: string[];
    };
    lastSelectedMenuKeys: string[];
    lastOpenKeys: string[];
    pageParams: Record<string, unknown>;
    breadcrumbItems: (string | { name: string; path: string })[];
    roleList: RoleItem[];
    paramsFromRoleManage: unknown;
}

type storgeType = keyof SessionStorageType | keyof LocalStorageType;

//Record<string, unknown>
type storageParams = Partial<SessionStorageType> | Partial<LocalStorageType>;

type storageKeyType = keyof storageParams;

const getObjFromStorage = (type: storeType) => {
    if (type === 'session') {
        return JSON.parse(sessionStorage.getItem(storageKeyName) || '{}');
    } else if (type === 'local') {
        return JSON.parse(localStorage.getItem(storageKeyName) || '{}');
    }
};

export const clearStorage = (type?: storeType): boolean => {
    if (type === 'session') {
        sessionStorage.clear();
    } else if (type === 'local') {
        localStorage.clear();
    } else {
        sessionStorage.clear();
        localStorage.clear();
    }
    return true;
};

//默认是local
export const setStorage = (param: storageParams, type: storeType = 'local'): boolean => {
    try {
        const objFromStorage: SessionStorageType | LocalStorageType = getObjFromStorage(type);
        let key: storageKeyType;
        for (key in param) {
            if (Object.prototype.hasOwnProperty.call(param, key)) {
                objFromStorage[key] = param[key];
            }
        }
        const objStr = JSON.stringify(objFromStorage);
        if (type === 'session') {
            sessionStorage.setItem(storageKeyName, objStr);
        } else {
            localStorage.setItem(storageKeyName, objStr);
        }
    } catch (e) {
        return false;
    }
    return true;
};

//默认是local
export const getStorage = (key: storgeType, type: storeType = 'local') => {
    const objFromStorage = getObjFromStorage(type);
    return objFromStorage[key];
};

export const getPageHash = (): string => window.location.hash.slice(1);

export const findMatchItemByPageHash = (): MenuType => {
    const pageHash = getPageHash();
    const menuList = getStorage('menuList') || [];
    const findItemsByHash = (_menuList: MenuType[], _findedItems: MenuType[] = []) => {
        if (Array.isArray(_menuList)) {
            for (const item of _menuList) {
                if (item.path) {
                    if (pageHash.includes(item.path)) {
                        _findedItems.push(item);
                    }
                }
                if (item.children) {
                    findItemsByHash(item.children, _findedItems);
                }
            }
        }
        return findedItems;
    };
    const findedItems = findItemsByHash(menuList);
    findedItems.sort((a, b) => {
        return b.path.length - a.path.length;
    });
    return findedItems[0];
};

export const findMenuItemById = (menuList: MenuType[], id: string): MenuType => {
    let targetItem = null;
    if (Array.isArray(menuList)) {
        for (const item of menuList) {
            if (item.id + '' === id + '') {
                targetItem = item;
                break;
            }
            if (item.children) {
                targetItem = findMenuItemById(item.children, id);
                if (targetItem) {
                    break;
                }
            }
        }
    }
    return targetItem;
};

//antd tdItem对象的配置
//?function.eslint@typescript-eslint/explicit-module-boundary-types
export const getTabTit = (arr: (string | number | null)[], render = undefined) => {
    const [title, key, width, fixed] = arr;
    let tdItem = {
        title,
        key,
        dataIndex: key,
        //默认超过长度自动省略
        ellipsis: true,
        fixed: undefined,
        render: undefined,
    };
    if (width && typeof width === 'number') {
        tdItem = Object.assign(tdItem, {
            width,
            render: (value) => {
                return (
                    <div title={value} className="ellipsis" style={{ minWidth: width + 'px', display: 'inline-block' }}>
                        {value}
                    </div>
                );
            },
        });
    }
    if (fixed) {
        tdItem.fixed = fixed;
    }
    if (typeof render === 'function') {
        tdItem.render = render;
    }
    return tdItem;
};

// 判断按钮的权限
export const judgePermList = (i) => {
    const permListKey = getStorage('permList');
    let sign = false;
    if (Array.isArray(permListKey)) {
        try {
            permListKey.forEach((item) => {
                if (item == i) {
                    sign = true;
                    throw new Error('找到了,退出forEach循环');
                }
            });
        } catch (e) {
            console.warn(e);
        }
    }
    return sign;
};

//是否在模板库演示环境 https://template-lib.i.wxblockchain.com/上
export const isOnDemoEnv = () => {
    return location.host === 'template-lib.i.wxblockchain.com' ? true : false;
};
export const mergeMockConfig = (apiConfig, mockConfig) => {
    const newMockConfig = {};
    for (const key in mockConfig) {
        let mockItem = mockConfig[key];
        //组装成对象
        if (typeof mockItem == 'string') {
            mockItem = {
                path: mockItem,
            };
        }

        if (mockItem.path.indexOf('/mock') !== 0) {
            mockItem.path = '/mock' + mockItem.path;
        }

        if (apiConfig[key]) {
            // 只复制 path,保留 apiConfig的 错误信息配置
            newMockConfig[key] = apiConfig[key];
            newMockConfig[key].path = mockItem.path;
        } else {
            //直接复制过来
            newMockConfig[key] = mockItem;
        }
    }
    console.log(newMockConfig, 'newMockConfig');
    return newMockConfig;
};

export const getServerAddrPrefix = () => {
    const env = (process_env + '').toLocaleLowerCase();
    //注意keyName可能写错
    if (env === 'production' && (window.apiConfig?.serverAddr || window.appConfig?.serverAddr)) {
        const { serverAddr } = window.apiConfig || window.appConfig;
        return serverAddr;
    } else {
        return '';
    }
};

export const handleRequestPath = (path: string, useMock = false) => {
    const env = (process_env + '').toLocaleLowerCase();
    const serverAddr = getServerAddrPrefix();
    //注意keyName可能写错
    if (env === 'production') {
        if (path.indexOf('http') === -1 && serverAddr) {
            path = serverAddr + path;
        }
    }
    // development下进入 mock模式
    if (env === 'development' && useMock) {
        if (path.indexOf('/mock') === -1) {
            path = `/mock${path}`;
        }
    }
    return path;
};

export const setShadowLabelWidth = (leftLabelWidth: string) => {
    return `.shadow-box {
        .shadow-inner-box {
            .ant-form-item-label {
                width: ${leftLabelWidth};
            }

            .form-item-box {
                padding-left: ${leftLabelWidth};
            }

            .form-btn-box {
                padding-left: ${leftLabelWidth};
            }
        }
    }`;
};

export const hasAuth = (curPerms) => {
    const frontCodeList = getStorage('frontCodeList') || [];
    return frontCodeList.includes(curPerms);
};

export const inputTrim = (form, keyName, e) => {
    const value = (e.target.value + '').trim();
    form.setFieldsValue({
        [keyName]: value,
    });
};

export const inputForbiddenWhiteSpace = (form, keyName, e) => {
    const value = (e.target.value + '').replace(/\s/g, '');
    form.setFieldsValue({
        [keyName]: value,
    });
};

//获取当前项目，真实menuList
export const getRealMenuList = (frontCodeList, originMenuList) => {
    // 根据权限码格式化菜单列表
    const formatMenuListByPermKey = () => {
        const menuData = {};
        const setMenuData = (list) => {
            list.forEach((item) => {
                menuData[item.perms] = item;
                if (Array.isArray(item.children) && item.children.length > 0) {
                    setMenuData(item.children);
                }
            });
        };
        setMenuData(originMenuList);
        return menuData;
    };

    const addMenuItem = (_frontCodeList, routeList, _menuList, breadcrumb, pId = '') => {
        const menuDataMap = formatMenuListByPermKey();
        routeList.forEach((item, index) => {
            const { permsKey, name, path, showOnMenu = true, icon, needValid = true } = item;
            if (!permsKey || !permsMap[permsKey]) {
                console.error(`${permsKey} - 该资源码不存在，请查证后再试`);
                return;
            }
            // 是否展示在菜单上
            // 1、有权限
            // 2、不需要校验
            if (showOnMenu && (_frontCodeList.includes(permsKey) || !needValid)) {
                const menuItem = {
                    name: menuDataMap[permsKey]?.name || name, // 优先使用后端返回的name,
                    path,
                    icon,
                    pId,
                    perms: permsKey,
                    breadcrumb: [...breadcrumb, { name, path }],
                    id: pId ? `${pId}_${index}` : index + '',
                    children: null,
                    orderNum: menuDataMap[permsKey]?.orderNum || 99999,
                };
                _menuList.push(menuItem);
                if (Array.isArray(item.children) && item.children.length > 0) {
                    menuItem.children = addMenuItem(_frontCodeList, item.children, [], [...menuItem.breadcrumb], menuItem.id);
                    //children需排序
                    menuItem.children.sort((a, b) => {
                        return a.orderNum - b.orderNum;
                    });
                }
            }
        });
        //增加排序功能,需同步到脚手架里
        _menuList.sort((a, b) => {
            return a.orderNum - b.orderNum;
        });
        return _menuList;
    };

    const getMenuList = () => {
        const _menuList = [];
        try {
            if (Array.isArray(routeMenuStructuredData)) {
                const menuRouteList = [...routeMenuStructuredData];
                const breadcrumb = [];
                const pId = null;
                addMenuItem(frontCodeList, menuRouteList, _menuList, breadcrumb, pId);
            }
            setStorage({ menuList: _menuList });
            return _menuList;
        } catch (e) {
            return _menuList;
        }
    };

    const menuList = getMenuList();
    menuList.sort((a, b) => a.orderNum - b.orderNum);
    return menuList;
};

export const copyText = (text: string) => {
    const oInput = document.createElement('input');
    oInput.value = text;
    document.body.appendChild(oInput);
    oInput.select(); // 选择对象;
    document.execCommand('Copy'); // 执行浏览器复制命令
    oInput.remove();
};

// 获取超级管理员的所有资源码
export const getFrontCodeListForAdmin = () => {
    const allPermsList = Object.keys(permsMap);
    const adminFrontCodeList = [];
    allPermsList.forEach((item) => {
        adminFrontCodeList.push(item);
    });
    return adminFrontCodeList;
};

type initSentryParamsType = {
    isProd: boolean;
    dsnProdKey: string;
    dsnTestKey: string;
    release: string;
    option?: Record<string, any>;
};

export const initSentry = ({ isProd, dsnProdKey, dsnTestKey, release, option = {} }: initSentryParamsType) => {
    Sentry.init({
        release,
        enabled: process.env.NODE_ENV === 'production',
        dsn: isProd ? dsnProdKey : dsnTestKey,
        integrations: [new BrowserTracing()],
        environment: document.location.host, // 配置不同环境标识
        ignoreErrors: [/ResizeObserver loop limit exceeded/i],
        // beforeSend(event, hint) {
        //   // 如果需要加入用户数据，可以在这里加入
        //   event.user = "用户信息";
        //   return event;
        // },
        // 抓取接口请求频率，用于性能评估，最大1.0。不建议设置过高。
        tracesSampleRate: 0.1,
        ...option,
    });
};

//为内页定义面包屑名称
export const initInnerPagesName = () => {
    const innerPagesRoutePermsMap = {};
    for (const k in permsMap) {
        const item = permsMap[k];
        //内页的判断依据
        if (item.name && item.path && item.showOnMenu === false) {
            //将
            let path = item.path;
            //有参数的路由分解keyName
            if (item.path.indexOf(':') > -1) {
                path = path.slice(0, item.path.indexOf(':') + 1);
            }
            innerPagesRoutePermsMap[path] = { ...item, component: undefined };
        }
    }
    // 以路由为key，将权限数据存储
    setStorage({ innerPagesRoutePermsMap });
};
